import 'package:flutter/material.dart';

import '../public.dart';

typedef OnCustomPageviewChange = void Function(int page);

/// 自定义PageView(水平翻页滑动)
class CustomPageview extends StatefulWidget {
  final List<Widget> children;
  final OnCustomPageviewChange onChange; // 页面改变事件
  final ScrollController controller; // 如果有传入滚动控制，则使用传入的
  final TabController tabController; // 可能与tabController联动

  CustomPageview(
      {Key key,
      this.children,
      this.onChange,
      this.controller,
      this.tabController})
      : super(key: key);

  @override
  _InState createState() {
    return _InState();
  }
}

class _InState extends State<CustomPageview> {
  var start; // 起始位置
  var isNextDirection; // 滚动方向
  var page = 0; // 当前页
  var screenWidth = ScreenUtil.getInstance().screenWidth; // 屏幕宽度
  ScrollController _scrollController;

  @override
  void initState() {
    super.initState();
    var tabController = widget.tabController;
    if (tabController != null) {
      tabController.addListener(() {
        page = tabController.index;
        widget.controller.animateTo(page * screenWidth,
            curve: Curves.linear, duration: Duration(milliseconds: 200));
      });
    }
    _scrollController = widget.controller ?? ScrollController();
  }

  @override
  void dispose() {
    _scrollController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Listener(
        onPointerDown: onPointerDown,
        onPointerUp: onPointerUp,
        child: ListView(
          physics: ClampingScrollPhysics(),
          scrollDirection: Axis.horizontal,
          controller: widget.controller,
          children: widget.children,
        ));
  }

  /// 手指按下
  void onPointerDown(PointerDownEvent event) {
    start = _scrollController.offset;
  }

  /// 手指抬起
  void onPointerUp(event) async {
    var diff = _scrollController.offset - start;
    // 拉动距离绝对值在30之间，不做处理
    if (diff.abs() <= 30) {
      _scrollController.animateTo(start,
          duration: Duration(milliseconds: 200), curve: Curves.linear);
      return;
    }

    isNextDirection = diff > 0;
    page = isNextDirection ? page + 1 : page - 1;
    if (widget.onChange != null) {
      widget.onChange(page);
    }
    var offset = isNextDirection ? start + screenWidth : start - screenWidth;
    _scrollController.animateTo(offset,
        duration: Duration(milliseconds: 200), curve: Curves.linear);
  }
}
